/**
  ******************************************************************************
  * @file    main.c
  * @author  ashuai0110
  * @version V2.0
  * @date    2024-09-03
  * @brief   使用举例-有限状态机FSM
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module
  *
  ******************************************************************************
  */

/* 包含头文件-----------------------------------------------------------------*/
#include "bsp.h"

#include "fsm_event_queue.h"
#include "led_blink.h"

/* 私有宏定义-----------------------------------------------------------------*/

/* 私有类型定义---------------------------------------------------------------*/

/* 私有变量-------------------------------------------------------------------*/
static led_blink_fsm_t ledBlinkFsm;             /* LED闪烁状态机 */
static led_blink_event_t ledBlinkEvent;         /* LED闪烁状态机事件 */
static fsm_eq_t ledBlinkFsmEq;                  /* LED闪烁状态机事件队列 */
static led_blink_event_t ledBlinkFsmEqBuf[10];  /* LED闪烁状态机事件队列缓冲区 */
/* 全局变量-------------------------------------------------------------------*/

/* 私有函数原型---------------------------------------------------------------*/


/**
  * @brief  This function handles SysTick Handler.
  *
  * @param  None
  *
  * @retval None
  */
void SysTick_Handler(void)
{
    /* 组件计时节拍接口 */
    mw_tick_inc(1);
    
    if(mw_tick_get() % 100 == 0)
    {
        /* 设置事件信号并写入事件队列 事件信号可以携带用户参数 */
        ledBlinkEvent.tick = mw_tick_get();
        ledBlinkEvent.super.signal = LED_BLINK_SIG_TICK;
        if(MW_RET_OK != fsm_eq_write(&ledBlinkFsmEq, (fsm_event_t *)&ledBlinkEvent, sizeof(ledBlinkEvent)))
        {
            MW_ERROR_LOG("fsm event queue write LED_BLINK_SIG_TICK error!");
        }
    }
}


/**
  * @brief  串口中断函数
  *
  * @param  None
  *
  * @retval None
  */
void USART1_IRQHandler(void)
{
    static uint8_t rxData;
    
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        rxData = USART_ReceiveData(USART1);
        switch(rxData)
        {
            case 'U':
                /* 设置事件信号并写入事件队列 */
                ledBlinkEvent.super.signal = LED_BLINK_SIG_UP;
                if(MW_RET_OK != fsm_eq_write(&ledBlinkFsmEq, (fsm_event_t *)&ledBlinkEvent, sizeof(ledBlinkEvent)))
                {
                    MW_ERROR_LOG("fsm event queue LED_BLINK_SIG_UP error!");
                }
                break;
            case 'D':
                /* 设置事件信号并写入事件队列 */
                ledBlinkEvent.super.signal = LED_BLINK_SIG_DOWN;
                if(MW_RET_OK != fsm_eq_write(&ledBlinkFsmEq, (fsm_event_t *)&ledBlinkEvent, sizeof(ledBlinkEvent)))
                {
                    MW_ERROR_LOG("fsm event queue write LED_BLINK_SIG_DOWN error!");
                }
                break;
            case 'O':
                /* 设置事件信号并写入事件队列 */
                ledBlinkEvent.super.signal = LED_BLINK_SIG_OK;
                if(MW_RET_OK != fsm_eq_write(&ledBlinkFsmEq, (fsm_event_t *)&ledBlinkEvent, sizeof(ledBlinkEvent)))
                {
                    MW_ERROR_LOG("fsm event queue write LED_BLINK_SIG_OK error!");
                }
                break;
        }
        
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}

/**
  * @brief  main
  */
int main(int argc, char *argv[])
{
    MW_VER_LOG("example-fsm_event_processor", 2, 0, 0);

    /* BSP初始化 */
    bsp_init();
    
    /* LED闪烁状态机初始构造 */
    led_blink_ctor(&ledBlinkFsm);
    /* FSM事件队列初始化 */
    fsm_eq_init(&ledBlinkFsmEq, (void *)ledBlinkFsmEqBuf, sizeof(ledBlinkFsmEqBuf));
    /* FSM初始化 */
    fsm_init((fsm_t *)&ledBlinkFsm, (fsm_event_t *)&ledBlinkEvent);
    
    while(1)
    {
        /* FSM事件队列读取事件信号 */
        if(MW_RET_OK == fsm_eq_read(&ledBlinkFsmEq, (fsm_event_t *)&ledBlinkEvent, sizeof(ledBlinkEvent)))
        {
            /* FSM事件派发 */
            fsm_dispatch((fsm_t *)&ledBlinkFsm, (fsm_event_t *)&ledBlinkEvent);
        }
    }
}

